﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;
using VLUSM_BusinessLogic.Helpers;
using VLUSM_BusinessLogic.DataTransferObjects;
using VLUSM_DataAccess;
using System.Data.SqlClient;
using System.Data.EntityClient;
using System.Data;
using System.Collections.ObjectModel;

namespace VLUSM_BusinessLogic
{
    public class PortfolioManager
    {
        IUnityContainer container;

        EntityConnection mainDataConnection;
        EntityConnection DVHCConnection;
        EntityConnection diemConnection;

        public PortfolioManager(IUnityContainer container)
        {
            this.container = container;
            this.Initialize();
        }

        #region LoaiHoSo Methods
        public ObservableCollection<LoaiHoSoDTO> GetLoaiHoSoList()
        {
            using (var context = container.Resolve<MainDataContainer>())
            {
                var result = context.LoaiHoSo;
                var oc = new ObservableCollection<LoaiHoSo>(result);
                return Converter.ConvertToLoaiHoSoDTOList(oc);
            }
        }

        public ObservableCollection<LoaiHoSoDTO> GetLoaiHoSoByDonViID(int DonViIDFilter)
        {
            using (var context = container.Resolve<MainDataContainer>())
            {
                var result = context.LoaiHoSo.Where(h => h.DonVis.Any(d => d.ID == DonViIDFilter));
                var oc = new ObservableCollection<LoaiHoSo>(result);
                return Converter.ConvertToLoaiHoSoDTOList(oc);
            }
        }

        public ObservableCollection<LoaiHoSoDTO> GetLoaiHoSoByNotYetDonViID(int DonViIDFilter)
        {
            using (var context = container.Resolve<MainDataContainer>())
            {
                var result = context.LoaiHoSo.Where(h => !h.DonVis.Any(d => d.ID == DonViIDFilter));
                var oc = new ObservableCollection<LoaiHoSo>(result);
                return Converter.ConvertToLoaiHoSoDTOList(oc);
            }
        }

        public LoaiHoSoDTO GetLoaiHoSoByID(int IDFilter)
        {
            using (var context = container.Resolve<MainDataContainer>())
            {
                var result = context.LoaiHoSo.Single(h => h.ID == IDFilter);
                return Converter.ConvertToLoaiHoSoDTO(result);
            }
        }

        public LoaiHoSoDTO GetLoaiHoSoByTen(string TenFilter)
        {
            using (var context = container.Resolve<MainDataContainer>())
            {
                var result = context.LoaiHoSo.Single(h => h.TenGoi == TenFilter);
                return Converter.ConvertToLoaiHoSoDTO(result);
            }
        }

        public void SaveLoaiHoSo(LoaiHoSoDTO objdto)
        {
            var obj = Converter.ConvertToLoaiHoSo(objdto);
            obj.NgayTao = DateTime.Today;
            using (var context = container.Resolve<MainDataContainer>())
            {
                context.LoaiHoSo.Attach(obj);
                if (obj.ID != 0)
                {
                    obj.NgayCapNhat = DateTime.Today;
                    context.ObjectStateManager.ChangeObjectState(obj, EntityState.Modified);
                }
                else
                {
                    obj.NgayCapNhat = null;
                    context.ObjectStateManager.ChangeObjectState(obj, EntityState.Added);
                }
                context.SaveChanges();
            }
        }

        public void SaveLoaiHoSoList(ObservableCollection<LoaiHoSoDTO> dtolist)
        {
            var list = Converter.ConvertToLoaiHoSoList(dtolist);
            using (var context = container.Resolve<MainDataContainer>())
            {
                foreach (var obj in list)
                {
                    obj.NgayCapNhat = DateTime.Today;
                    context.LoaiHoSo.Attach(obj);
                    if (obj.ID != 0)
                    {
                        context.ObjectStateManager.ChangeObjectState(obj, EntityState.Modified);
                    }
                    else
                    {
                        context.ObjectStateManager.ChangeObjectState(obj, EntityState.Added);
                    }
                }
                context.SaveChanges();
            }
        }

        public void RemoveLoaiHoSo(LoaiHoSoDTO objdto)
        {
            var obj = Converter.ConvertToLoaiHoSo(objdto);
            using (var context = container.Resolve<MainDataContainer>())
            {
                context.LoaiHoSo.Attach(obj);
                context.ObjectStateManager.ChangeObjectState(obj, EntityState.Deleted);
                context.SaveChanges();
            }
        }

        public void RemoveLoaiHoSoByID(int IDFilter)
        {
            using (var context = container.Resolve<MainDataContainer>())
            {
                var obj = context.LoaiHoSo.Single(h => h.ID == IDFilter);
                context.LoaiHoSo.Attach(obj);
                context.ObjectStateManager.ChangeObjectState(obj, EntityState.Deleted);
                context.SaveChanges();
            }
        }

        public void UnSetQuyenListForDonVi(int DonViID, ObservableCollection<QuyenDTO> listDTO)
        {
            using (var context = container.Resolve<MainDataContainer>())
            {
                var donViQuery = context.DonVi.Single(d => d.ID == DonViID);

                foreach (var quyendto in listDTO)
                {
                    var quyen = context.Quyen.FirstOrDefault(q => q.ID == quyendto.ID);
                    donViQuery.Quyens.Attach(quyen);
                    donViQuery.Quyens.Remove(quyen);
                }
                context.SaveChanges();
            }
        }

        public void SetLoaiHoSoForDonVi(int DonViID, int LoaiHoSoID)
        {
            using (var context = container.Resolve<MainDataContainer>())
            {
                var donViQuery = context.DonVi.Single(d => d.ID == DonViID);
                var loaiHoSoQuery = context.LoaiHoSo.Single(h => h.ID == LoaiHoSoID);
                if (!donViQuery.LoaiHoSoes.Contains(loaiHoSoQuery))
                {
                    donViQuery.LoaiHoSoes.Add(loaiHoSoQuery);
                }
                context.SaveChanges();
            }
        }

        public void SetLoaiHoSoListForDonVi(int DonViID, ObservableCollection<LoaiHoSoDTO> listDTO)
        {
            using (var context = container.Resolve<MainDataContainer>())
            {
                var donViQuery = context.DonVi.Single(d => d.ID == DonViID);
                var list = Converter.ConvertToLoaiHoSoList(listDTO);
                foreach (var loaihoso in list)
                {
                    donViQuery.LoaiHoSoes.Add(loaihoso);
                }
                foreach (var loaihoso in donViQuery.LoaiHoSoes)
                {
                    context.ObjectStateManager.ChangeObjectState(loaihoso, EntityState.Unchanged);
                }
                context.SaveChanges();
            }
        }

        public void UnsetLoaiHoSoForDonVi(int DonViID, int LoaiHoSoID)
        {
            using (var context = container.Resolve<MainDataContainer>())
            {
                var donViQuery = context.DonVi.Single(d => d.ID == DonViID);
                var loaiHoSoQuery = context.LoaiHoSo.Single(h => h.ID == LoaiHoSoID);

                donViQuery.LoaiHoSoes.Remove(loaiHoSoQuery);
                context.SaveChanges();
            }
        }

        public void UnSetLoaiHoSoListForDonVi(int DonViID, ObservableCollection<LoaiHoSoDTO> listDTO)
        {
            using (var context = container.Resolve<MainDataContainer>())
            {
                var donViQuery = context.DonVi.Single(d => d.ID == DonViID);

                foreach (var loaihosodto in listDTO)
                {
                    var loaihoso = context.LoaiHoSo.FirstOrDefault(h => h.ID == loaihosodto.ID);
                    donViQuery.LoaiHoSoes.Attach(loaihoso);
                    donViQuery.LoaiHoSoes.Remove(loaihoso);
                }
                context.SaveChanges();
            }
        }

        #endregion

        #region PhienBanGiao Methods
        public ObservableCollection<PhienBanGiaoDTO> GetPhienBanGiaoList()
        {
            using (var context = container.Resolve<MainDataContainer>())
            {
                var result = context.PhienBanGiao;
                var oc = new ObservableCollection<PhienBanGiao>(result);
                return Converter.ConvertToPhienBanGiaoDTOList(oc);
            }
        }

        public PhienBanGiaoDTO GetPhienBanGiaoByID(int IDFilter)
        {
            using (var context = container.Resolve<MainDataContainer>())
            {
                var result = context.PhienBanGiao.Single(p => p.ID == IDFilter);
                return Converter.ConvertToPhienBanGiaoDTO(result);
            }
        }

        public PhienBanGiaoDTO GetPhienBanGiaoByTen(string TenFilter)
        {
            using (var context = container.Resolve<MainDataContainer>())
            {
                var result = context.PhienBanGiao.Single(p => p.TenGoi == TenFilter);
                return Converter.ConvertToPhienBanGiaoDTO(result);
            }
        }

        public ObservableCollection<PhienBanGiaoDTO> GetPhienBanGiaoByDonViID(int DonViIDFIlter)
        {
            using (var context = container.Resolve<MainDataContainer>())
            {
                var result = context.PhienBanGiao.Where(p => p.DonViID == DonViIDFIlter);
                var oc = new ObservableCollection<PhienBanGiao>(result);
                return Converter.ConvertToPhienBanGiaoDTOList(oc);
            }
        }

        public void SavePhienBanGiao(PhienBanGiaoDTO objdto)
        {
            var obj = Converter.ConvertToPhienBanGiao(objdto);
            obj.NgayBanGiao = DateTime.Today;
            using (var context = container.Resolve<MainDataContainer>())
            {
                context.PhienBanGiao.Attach(obj);
                if (obj.ID != 0)
                {
                    context.ObjectStateManager.ChangeObjectState(obj, EntityState.Modified);
                }
                else
                {
                    context.ObjectStateManager.ChangeObjectState(obj, EntityState.Added);
                }
                context.SaveChanges();
            }
        }

        public void SavePhienBanGiaoList(ObservableCollection<PhienBanGiaoDTO> dtolist)
        {
            var list = Converter.ConvertToPhienBanGiaoList(dtolist);
            using (var context = container.Resolve<MainDataContainer>())
            {
                foreach (var obj in list)
                {
                    context.PhienBanGiao.Attach(obj);
                    if (obj.ID != 0)
                    {
                        context.ObjectStateManager.ChangeObjectState(obj, EntityState.Modified);
                    }
                    else
                    {
                        context.ObjectStateManager.ChangeObjectState(obj, EntityState.Added);
                    }
                }
                context.SaveChanges();
            }
        }

        public void RemovePhienBanGiao(PhienBanGiaoDTO objdto)
        {
            var obj = Converter.ConvertToPhienBanGiao(objdto);
            using (var context = container.Resolve<MainDataContainer>())
            {
                context.PhienBanGiao.Attach(obj);
                context.ObjectStateManager.ChangeObjectState(obj, EntityState.Deleted);
                context.SaveChanges();
            }
        }

        public void RemovePhienBanGiaoByID(int IDFilter)
        {
            using (var context = container.Resolve<MainDataContainer>())
            {
                try
                {
                    var obj = context.PhienBanGiao.Single(h => h.ID == IDFilter);
                    context.PhienBanGiao.Attach(obj);
                    context.ObjectStateManager.ChangeObjectState(obj, EntityState.Deleted);
                    context.SaveChanges();
                }
                catch { }
            }
        }
        #endregion

        #region HoSoDaNop
        public ObservableCollection<HoSoDaNopDTO> GetHoSoDaNopList()
        {
            using (var context = container.Resolve<MainDataContainer>())
            {
                var result = context.HoSoDaNop;
                var oc = new ObservableCollection<HoSoDaNop>(result);
                return Converter.ConvertToHoSoDaNopDTOList(oc);
            }
        }

        public ObservableCollection<HoSoDaNopDTO> GetHoSoDaNopBySinhVienID(int SinhVienIDFilter)
        {
            using (var context = container.Resolve<MainDataContainer>())
            {
                var result = context.HoSoDaNop.Where(h => h.SinhVienID == SinhVienIDFilter);
                var oc = new ObservableCollection<HoSoDaNop>(result);
                return Converter.ConvertToHoSoDaNopDTOList(oc);
            }
        }

        public ObservableCollection<HoSoDaNopDTO> GetHoSoDaNopByLoaiHoSoID(int LoaiHoSoIDFilter)
        {
            using (var context = container.Resolve<MainDataContainer>())
            {
                var result = context.HoSoDaNop.Where(h => h.LoaiHoSoID == LoaiHoSoIDFilter);
                var oc = new ObservableCollection<HoSoDaNop>(result);
                return Converter.ConvertToHoSoDaNopDTOList(oc);
            }
        }

        public HoSoDaNopDTO GetHoSoDaNopByID(int IDFilter)
        {
            using (var context = container.Resolve<MainDataContainer>())
            {
                var result = context.HoSoDaNop.Single(h => h.ID == IDFilter);
                return Converter.ConvertToHoSoDaNopDTO(result);
            }
        }

        public void SaveHoSoDaNop(HoSoDaNopDTO objdto)
        {
            var obj = Converter.ConvertToHoSoDaNop(objdto);
            using (var context = container.Resolve<MainDataContainer>())
            {
                try
                {
                    context.HoSoDaNop.Attach(obj);
                    if (obj.ID != 0)
                    {
                        context.ObjectStateManager.ChangeObjectState(obj, EntityState.Modified);
                    }
                    else
                    {
                        context.ObjectStateManager.ChangeObjectState(obj, EntityState.Added);
                    }
                    context.SaveChanges();
                }
                catch { }
            }
        }

        public void SaveHoSoDaNopList(ObservableCollection<HoSoDaNopDTO> dtolist)
        {
            var list = Converter.ConvertToHoSoDaNopList(dtolist);
            using (var context = container.Resolve<MainDataContainer>())
            {
                foreach (var obj in list)
                {
                    context.HoSoDaNop.Attach(obj);
                    if (obj.ID != 0)
                    {
                        context.ObjectStateManager.ChangeObjectState(obj, EntityState.Modified);
                    }
                    else
                    {
                        context.ObjectStateManager.ChangeObjectState(obj, EntityState.Added);
                    }
                }
                context.SaveChanges();
            }
        }

        public void RemoveHoSoDaNop(HoSoDaNopDTO objdto)
        {
            var obj = Converter.ConvertToHoSoDaNop(objdto);
            using (var context = container.Resolve<MainDataContainer>())
            {
                context.HoSoDaNop.Attach(obj);
                context.ObjectStateManager.ChangeObjectState(obj, EntityState.Deleted);
                context.SaveChanges();
            }
        }

        public void RemoveHoSoDaNopByID(int IDFilter)
        {
            using (var context = container.Resolve<MainDataContainer>())
            {
                try
                {
                    var obj = context.HoSoDaNop.Single(h => h.ID == IDFilter);
                    context.HoSoDaNop.Attach(obj);
                    context.ObjectStateManager.ChangeObjectState(obj, EntityState.Deleted);
                    context.SaveChanges();
                }
                catch { }
            }
        }
        #endregion

        #region Private Methods
        private void Initialize()
        {
            DVHCConnection = EntityConnectionCreator.Instance.DonViHanhChinhConnection;
            mainDataConnection = EntityConnectionCreator.Instance.MainDataConnection;
            diemConnection = EntityConnectionCreator.Instance.DiemConnection;

            this.UnityRegisterType();
            this.InitializeMapper();
        }

        private void UnityRegisterType()
        {
            container.RegisterType<MainDataContainer>(new InjectionConstructor(mainDataConnection));
        }

        private void InitializeMapper()
        {
            Converter.ConfigureLoaiHoSoMapping();
            Converter.ConfigurePhienBanGiaoMapping();
            Converter.ConfigureHoSoDaNopMapping();
        }
        #endregion
    }
}
